package com.great.codewars;

import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * 阶乘的方法
 *@author   schumi
 */
public class Factorial {
    //较大值时
    public String BigInt(int n) {
        if (n < 0) {
            return null;
        }
        BigInteger a = new BigInteger("1");
        for (int i = 1; i < n + 1; i++) {
            a = a.multiply(new BigInteger("" + i));
        }
        return a.toString();
    }

    public  String BigInt1(int n) {
        if(n<0){
            return  null;
        }
        else if(n == 1 || n==0){
            return BigDecimal.valueOf(1).toString();
        }else{
            return BigDecimal.valueOf(n).multiply(new BigDecimal(BigInt1(n-1))).toString();
        }
    }

    /**
     * 递归
     * @param n
     */
    int fact(int n){
        return fact_iter(n,1);
    }

    int fact_iter(int n, int product){
        if(n == 1 || n == 0){
            System.out.println("step n=" + n +" value:"+product);
            return 1*product;
        }else{
            System.out.println("step n=" + n +" value:"+product);
            return fact_iter((n-1),n*product);
        }
    }

    /**
     *尾递归
     * @param n
     * @return
     */
    int factN(int n){
        if(n == 1 || n==0){
            return 1;
        }else{
            return n*factN(n - 1);
        }
    }

    /**
     * 循环
     * @param n
     * @return
     */
    int factFor(int n){
        int sum = 1;

        if(n == 0){
            return 1;
        }
        for(int i = 1; i <= n; i++){
            sum*=i;
        }
        return sum;
    }
    public static void main(String[] args) {
       Factorial f=new Factorial();
        String bigInt = f.BigInt(5);
        System.out.println(bigInt);
        String s = f.BigInt1(5);
        System.out.println(s);
        int fact = f.fact(5);
        System.out.println(fact);
        int i = f.factN(5);
        System.out.println(i);
        int i1 = f.factFor(5);
        System.out.println(i1);
    }
}
